home *** CD-ROM | disk | FTP | other *** search
Text File | 1989-07-31 | 13.3 KB | 556 lines | [TEXT/R*ch] |
- /*
- * @(#)sysdep.amiga 1.2 87/09/23 Copyright 1987 Free Software Foundation, Inc.
- *
- * Copying and use of this program are controlled by the terms of the
- * GNU Emacs General Public License.
- */
-
- #ifndef lint
- char sysdep_version[] = "@(#)sysdep.amiga gnuucp Version hoptoad-1.2";
- #endif
-
- /*
- * Created 23 Sept 1987 by John Gilmore, using material from sysdep.unix
- * and from an older Amiga uuslave port by:
- * William Loftus (burdvax!wpl), Feb 1987
- */
-
- #include "includes.h"
- #include "uucp.h"
- #include "sysdep.h"
-
- #define MULTITASK
- #define STDIN 0
- #define LIBDIR "/usr/lib/uucp"
- #define CONTROL "/usr/lib/uucp/gnuucp.ctl"
- #define PUBDIR "/usr/spool/uucppublic"
- #define LOGFILE "LOGFILE"
- #define O_BINARY 0 /* No distinction between text and binary */
-
- /*
- * Exported variables
- */
- char sysdep_control[] = CONTROL;
-
-
- /* Our variables */
-
- /* Declarations for the serial read and write. */
- extern struct MsgPort *CreatePort();
- struct IOExtSer *Read_Request;
- static char rs_in[2];
- struct IOExtSer *Write_Request;
- static char rs_out[2];
- struct timerequest Timer;
- struct MsgPort *Timer_Port = NULL;
-
- void sigint(); /* Forward declaration */
-
- /*
- * Open the serial line for an incoming call.
- * Argument of NULL or empty string means stdin.
- */
- int
- openline(ttynam, baud)
- char *ttynam;
- int baud;
- {
- int ontheline = !(ttynam && ttynam[0]); /* FIXME, this is garbage */
- int c;
-
- Read_Request =
- (struct IOExtSer *)AllocMem(sizeof(*Read_Request),
- MEMF_PUBLIC|MEMF_CLEAR);
-
- Read_Request->io_SerFlags = SERF_SHARED | SERF_XDISABLED;
- Read_Request->IOSer.io_Message.mn_ReplyPort =
- CreatePort("Read_RS",0);
-
- if(OpenDevice(SERIALNAME,NULL,Read_Request,NULL)) {
- printf("Can not open serial port for read.\n");
- DeletePort(Read_Request->IOSer.io_Message.mn_ReplyPort);
- FreeMem(Read_Request,sizeof(*Read_Request));
- exit(TRUE);
- }
-
- Read_Request->IOSer.io_Length = 1;
- Read_Request->IOSer.io_Data = (APTR) &rs_in[0];
-
- Write_Request =
- (struct IOExtSer *)AllocMem(sizeof(*Write_Request),
- MEMF_PUBLIC|MEMF_CLEAR);
-
- Write_Request->io_SerFlags = SERF_SHARED | SERF_XDISABLED;
-
- Write_Request->IOSer.io_Message.mn_ReplyPort =
- CreatePort("Write_RS",0);
-
- if(OpenDevice(SERIALNAME,NULL,Write_Request,NULL)) {
- printf("Can not open open serial port for write.\n");
- DeletePort(Write_Request->IOSer.io_Message.mn_ReplyPort);
- FreeMem(Write_Request,sizeof(*Write_Request));
- DeletePort(Read_Request->IOSer.io_Message.mn_ReplyPort);
- FreeMem(Read_Request,sizeof(*Read_Request));
- exit(TRUE);
- }
-
- Write_Request->IOSer.io_Command = CMD_WRITE;
- Write_Request->IOSer.io_Length = 1;
- Write_Request->IOSer.io_Data = (APTR) &rs_out[0];
-
- Read_Request->io_SerFlags = 0L;
- Read_Request->io_Baud = baud;
- Read_Request->io_ReadLen = 8L;
- Read_Request->io_WriteLen = 8L;
- Read_Request->io_CtlChar = 0x11130000L;
- Read_Request->io_BrkTime = 750000;
- Read_Request->IOSer.io_Command = SDCMD_SETPARAMS;
-
- DoIO(Read_Request);
-
- Read_Request->IOSer.io_Command = CMD_READ;
-
- Timer_Port = CreatePort("Timer Port",0L);
-
- if (OpenDevice(TIMERNAME, UNIT_VBLANK, (char *) &Timer, 0)) {
- printf("Can't open timer device.");
- DeletePort(Write_Request->IOSer.io_Message.mn_ReplyPort);
- FreeMem(Write_Request,sizeof(*Write_Request));
- DeletePort(Read_Request->IOSer.io_Message.mn_ReplyPort);
- FreeMem(Read_Request,sizeof(*Read_Request));
- exit(TRUE);
- }
-
- Timer.tr_node.io_Message.mn_ReplyPort = Timer_Port;
- Timer.tr_node.io_Command = TR_ADDREQUEST;
- Timer.tr_node.io_Flags = 0;
- Timer.tr_node.io_Error = 0;
-
- BeginIO(Read_Request);
- xwrite(msgo6,sizeof(msgo6)-1); /* set up terminal */
-
- signal(SIGINT,sigint);
-
- begin_again:
- printf("Start again!!\n");
-
- c = xgetc();
- while (c == EOF) { c = xgetc(); printf(".");} /* wait for input */
-
- printf("\nHey what was that?\n");
- printf("Got %c\n %d %d %c",c,c,c & 0xFF,c & 0xFF);
-
- /* now we have something !! */
- /* Not nice, but fast! */
-
- if ((c) == 'C') {
- c = xgetc();
- printf("C got %c\n",c);
- if ((c) == 'O') {
- c = xgetc();
- printf("CO got %c\n",c);
- if ((c) == 'N') {
- c = xgetc();
- if ((c) == 'N') {
- c = xgetc();
- if ((c) == 'E') {
- c = xgetc();
- if ((c) == 'C') {
- c = xgetc();
- if ((c) == 'T') {
- c = xgetc();
- if ((c) == ' ') {
- c = xgetc();
- if ((c) == '1') {
- c = xgetc();
- if ((c) == '2') {
- c = xgetc();
- if ((c) == '0') {
- c = xgetc();
- if ((c) == '0') {
- c = xgetc();
- if ((c) == '\r') {
- DEBUG(1,"Someone is rapping, rapping at my ...\n", 0);
- /* do it !!! */
- c = xgetc();
- while (c != EOF) c = xgetc(); /* zap trash*/
- return;
- } else goto begin_again;
- } else goto begin_again;
- } else goto begin_again;
- } else goto begin_again;
- } else goto begin_again;
- } else goto begin_again;
- } else goto begin_again;
- } else goto begin_again;
- } else goto begin_again;
- } else goto begin_again;
- } else goto begin_again;
- } else goto begin_again;
- } else goto begin_again;
- }
-
- /*
- * Open the serial line for an outgoing call.
- */
- int
- openout(ttynam, baud)
- char *ttynam;
- int baud;
- {
-
- abort(); / FIXME -- write for amiga */
-
- signal(SIGINT,sigint);
- return SUCCESS;
- }
-
- /*
- * Basement level I/O routines
- *
- * xwrite() writes a character string to the serial port
- * xgetc() returns a character from the serial port, or an EOF for timeout.
- * sigint() restores the state of the serial port on exit.
- * hangup() hangs up the serial port (e.g. drop DTR).
- */
-
- int
- xgetc()
- {
- int rd,ch;
-
- /* printf("\nxgetc\n"); */
-
- Timer.tr_time.tv_secs = BYTE_TIMEOUT;
- Timer.tr_time.tv_micro = 0;
- SendIO((char *) &Timer.tr_node);
- /* BeginIO((char *) &Timer.tr_node);*/
-
- rd = FALSE;
- while (rd == FALSE)
- {
- Wait((1L << Read_Request->IOSer.io_Message.mn_ReplyPort->mp_SigBit) |
- ( 1L << Timer_Port->mp_SigBit));
- if (CheckIO(Read_Request)) {
- WaitIO(Read_Request);
- ch=rs_in[0];
- rd = TRUE;
- SendIO(Read_Request);
- }
- if (rd == FALSE && CheckIO((char*) &Timer)) {
- WaitIO((char*)&Timer);
- /*printf("TIMEOUT\n");*/
- return(EOF); /* Time out!!! */
- }
- } /* end while */
-
- /* printf("Before AbortIO & Wait \n"); */
-
- if (!CheckIO((char *) &Timer))
- AbortIO((char *) &Timer);
- else
- WaitIO((char *) &Timer);
-
- /* Wait (1L << Timer_Port->mp_SigBit); */
- /* printf(" Returning '%c'\n",ch & 0xFF); */
-
- return(ch);
- }
-
- int
- xwrite(buf,ctr)
- char *buf;
- int ctr;
- {
- int i;
-
- for (i=0; i < ctr; i++) {
- rs_out[0] = (*buf++) & 0xFF;
- DoIO(Write_Request);
- }
- return 1;
- }
-
- sigint()
- {
- CloseDevice(Write_Request);
- DeletePort(Write_Request->IOSer.io_Message.mn_ReplyPort);
- FreeMem(Write_Request,sizeof(*Write_Request));
- CloseDevice(Read_Request);
- DeletePort(Read_Request->IOSer.io_Message.mn_ReplyPort);
- FreeMem(Read_Request,sizeof(*Read_Request));
- DeletePort(Timer_Port);
- printf("User requested termination.\n");
- exit(TRUE);
- }
-
- /*
- * hangup(): hang up the 'fone.
- */
- int
- hangup()
- {
-
- abort(); /* FIXME -- write for Amiga */
- sleep(2); /* To be sure DTR stays down that long */
- }
-
-
- /*
- * Create a temporary file name for receiving a file into.
- * "name" is the name we will actually eventually want to use for the file.
- * We currently ignore it, but some OS's that can't move files around
- * easily might want to e.g. put the temp file into the same directory
- * that this file is going into.
- *
- * FIXME:
- * This interface should be able to return a "possible" filename, and
- * be re-called if the name is already in use, to get another.
- * This avoids checking here whether the name is good -- saving system calls.
- */
- char *
- temp_filename(name)
- register char *name;
- {
- static char tname[NAMESIZE];
-
- if (ourpid == 0)
- ourpid = getpid();
- (void) sprintf(tname, "TM.u%d", ourpid);
- DEBUG(7, "Using temp file %s\n", tname);
- return tname;
- }
-
-
- /*
- * Transform a filename from a uucp packet (in Unix format) into a local
- * filename that will work in the local file system.
- */
- char *
- munge_filename(name)
- register char *name;
- {
- register char *p;
- static char buffer[NAMESIZE+SLOP];
- int len, hostlen;
-
- DEBUG(7, "Munge_filename input: %s\n", name);
-
- /* FIXME: Security checking goes here! */
-
- if (name[0] == '~') {
- /* Handle user-relative names -- ~ or ~uucp turns to PUBDIR */
- if (name[1] == '/')
- p = &name[1];
- else if (!strncmp("~uucp/", name, 6))
- p = &name[5];
- else {
- p = NULL; /* Neither of the above */
- goto out;
- }
- strcpy(buffer, PUBDIR);
- strcat(buffer, p);
- p = buffer;
- goto out;
- }
-
- #ifdef SUBDIR
- /* Berkeley Unix subdirectory hack.
- * Full pathnames go through OK.
- * D.myname* -> D.myname/D.myname*
- * D.* -> D./D.*
- * C.* -> C./C.*
- * otherwise left alone (e.g. X.*, LCK.*, STST.*).
- * FIXME: I hear Honey Danber has a slightly different scheme.
- * In particular, STST's go in a directory.
- */
- if (name[0] != '/') {
- if (name[1] == '.' &&
- (name[0] == 'C' || name[0] == 'D')) {
- len = strlen(name);
- hostlen = strlen(Myname);
- if (hostlen > 7) hostlen = 7;
- /* Check D.mynameAxxxx case */
- if (name[0] == 'D' && len == hostlen + 2 + 5 &&
- !strncmp(&name[2], Myname, hostlen))
- len = 2 + hostlen; /* "D."+name */
- else
- len = 2; /* Just "D." */
- strcpy(buffer, name);
- buffer[len] = '/';
- strcpy(buffer+len+1, name);
- p = buffer;
- goto out;
- }
- }
- #endif
-
- p = name; /* Let it through as-is. */
-
- out:
- DEBUG(7, "Munge_filename output: %s\n", p);
- return p;
- }
-
- /*
- * Uucp work queue scan.
- *
- * gotsome = work_scan(hostname, type);
- * workfile = work_next();
- * void work_done();
- */
-
- /*
- * Local variables of the work queue scanner -- not visible to outsiders
- *
- * Workhost and worktype are always null-terminated; keeping their lengths
- * is just a performance hack. Workprefix is NOT null terminated; various
- * people copy things after it and use the whole string. Workprefix is
- * exactly workplen long; to append something, strcpy(workprefix+workplen, ...)
- */
- #define MAX_TYPE 10
- static DIR *workdir = (DIR *)NULL;
- static struct dirent *workfile;
- static char workhost[MAX_HOST+1];
- static int workhlen;
- static char worktype[MAX_TYPE+1];
- static int worktlen;
- static char workfirst = 0;
- /* FIXME, at the moment this can be local to work_scan() */
- static char workprefix[MAX_TYPE+1+MAX_HOST+1+MAX_TYPE+1+MAX_HOST+6+SLOP];
- /* D . hoptoad / D . hoptoad N1234\0 */
- static int workplen;
-
- void
- work_done()
- {
- if (workdir)
- closedir(workdir);
- workdir = (DIR *) NULL;
- workfile = (struct dirent *) NULL;
- workfirst = 0;
- }
-
-
- int
- work_scan(host, type)
- char *host;
- char *type;
- {
- char *p;
-
- if (!host)
- host = "";
-
- /* If called twice in a row, don't thrash the disk again */
- if (strcmp(workhost, host) == SAME &&
- strcmp(worktype, type) == SAME && workfile)
- return 1;
-
- if (workdir) work_done(); /* Clean up prev call */
-
- workfirst = 1; /* Initialize for work_next */
- workhlen = strlen(host);
- if (workhlen > sizeof (workhost) -1) abort();
- strcpy(workhost, host);
- if (workhlen > 7) workhlen = 7; /* Unix uucp limit */
- worktlen = strlen(type);
- if (worktlen > sizeof (worktype) -1) abort();
- strcpy(worktype, type);
-
- /* Figure out which subdirectory this class of files is in. */
- /* FIXME: doesn't handle "all D. files" since D.myname is separate. */
- sprintf(workprefix, "%s.%s", worktype, workhost);
- p = munge_filename(workprefix);
- strcpy(workprefix, p);
- p = index(workprefix, '/');
- if (p)
- workplen = 1 + p - workprefix; /* Prefix ends after '/' */
- else
- workplen = 0; /* No / in munged; hence no dir */
- workprefix[workplen] = '\0';
- DEBUG(7, "Work prefix is =%s=\n", workprefix);
-
- strcpy(workprefix+workplen, ".");
- workdir = opendir(workprefix); /* Open whatever directory */
- if (workdir == NULL) {
- DEBUG(0, "Can't open queue directory %s\n", workprefix);
- return 0; /* No work */
- }
-
- return work_look();
- }
-
-
- static int
- work_look()
- {
- int len;
-
- for (;;) {
- workfile = readdir(workdir);
- if (workfile == NULL) {
- DEBUG(7, "work_look readdir null\n", 0);
- work_done();
- return 0; /* No work */
- }
- DEBUG(7, "work_look readdir %s\n", workfile->d_name);
-
- /* Is it the right type? */
- if (strncmp(workfile->d_name, worktype, worktlen) == SAME
- && workfile->d_name[worktlen] == '.') {
- /* see if it matches the hostname */
- len = strlen(workfile->d_name);
- /* "C" "." "hoptoad" "Xnnnn" */
- if (workhlen == 0 ||
- (len == worktlen + 1 + workhlen + 5 &&
- !strncmp(workhost, workfile->d_name+2, workhlen))
- ) {
- /* Found an entry! */
- /* FIXME, check grade letter! */
- DEBUG(7, "work_look found it!\n", 0);
- return 1; /* Found work */
- }
- }
- }
- /* NOTREACHED */
- }
-
-
- char *
- work_next()
- {
-
- if (!workfirst) {
- if (!workfile || !work_look())
- return (char *)NULL;
- }
- workfirst = 0;
-
- return workfile->d_name;
- }
-
- /*
- * Routine to return a string that gives the current date and time, and
- * identifies the current process, if on a multiprocess system.
- */
- char *
- time_and_pid()
- {
- long clock;
- struct tm *tm;
- static int ourpid = 0;
- static char format[] = "%d/%d-%d:%02d:%02d-%d";
- static char outbuf[sizeof(format)];
-
- (void) time(&clock);
- tm = localtime(&clock);
- if (ourpid == 0)
- ourpid = getpid();
- sprintf(outbuf, format,
- tm->tm_mon+1, tm->tm_mday,
- tm->tm_hour, tm->tm_min, tm->tm_sec,
- ourpid);
- return outbuf;
- }
-